/******************************************************************************
 *  _____     _____
 *  \  __\    \  __\
 *   \ \_\\    \ \_\\
 *    \  __\SS  \  __\roject
 *     \_\       \_\
 *
 * Mateusz Maciąg, Rafał Urbański
 * Komputerowe Systemy Sterowania
 *****************************************************************************/

#ifndef PIDCONTROLLER_H
#define PIDCONTROLLER_H

#include "ControllerBase.h"
#include "SimInterface/ISimulator.h"

// Przestrzeń nazw
namespace RafMat
{
namespace SimEngine
{

/**
  Klasa regulatora PID.

  Klasa implementuje bazowy regulatora ControllerBase.
  Reprezentuje regulator PID z częścią różniczującą
  rzeczywistą.

  Zmiana parametrów jest bezpieczna pod kątem wyjątków
  pod warunkiem, że zmienia się wszystkie na raz
  (specjalna komenda "*").
*/
class PIDController : public ControllerBase
{
public:
    PIDController(SimInterface::ISimulator &isim, double gain = 1,
                  double ti = 0, double td = 0);

    //
    // Implementacja IConfigurable
    //

    /** Ustawia parametr (\see IConfigurable::setParameter). */
    bool setParameter(const std::string& param, const std::string& value) throw(std::logic_error);

    /** Odczytuje parametr (\see IConfigurable::getParameter). */
    std::string getParameter(const std::string& param) const throw(std::logic_error);

    /**
        Resetuje regulator kasująć jego pamięć próbek.
    */
    void reset();

protected:
    /**
        Wykonuje krok przeliczeń stanu regulatora PID.
    */
    double simulateControllerStep(double setPoint, double processVar);

    /**
        Wyrzuca parametry do strumienia konfiguracyjnego.
    */
    SimFile::ConfigWriter& dumpSpecificPar(SimFile::ConfigWriter& o) const;

private:
    // Stałe konfiguracyjne
    static const std::string CONF_ALL;
    static const std::string CONF_GAIN;
    static const std::string CONF_B;
    static const std::string CONF_TI;
    static const std::string CONF_TD;
    static const std::string CONF_N;
    static const std::string CONF_UBOUND;
    static const std::string CONF_LBOUND;

    /**
        Ustawia wszystkie parametry regulatora PID.
        Funkcja daje silną gwarancję bezpieczeństwa.

        \param [in] values Parametry regulatora w forme wektora [ ... ].
    */
    void safeSetParameters(const std::string& values);

    // Do części proporcjonalnej:
    double m_k;             ///< Wzmocnienie (wpływa też na część I i D!).
    double m_b;             ///< Parametr w równaniu uchybu e = rb-y. Typowo b = 1

    // Do części całkującej:
    double m_ti;            ///< Czas zdwojenia (przeliczony na próbki!).
    double m_tiSum;

    // Do części różniczkującej:
    double m_td;        ///< Czas wyprzedzenia części różniczkującej.
    double m_N;

    // Ograniczenie:
    double m_upperBound;
    double m_lowerBound;

    // Pozostałe:
    double m_Dm1;  // D(i-1).
    double m_em1;  // y(i-1).
};

}
}

#endif // PIDCONTROLLER_H

